/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controladores;

import controladores.exceptions.IllegalOrphanException;
import controladores.exceptions.NonexistentEntityException;
import controladores.exceptions.PreexistingEntityException;
import entidades.Solicitud;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.Carta;
import entidades.Solicitudinsumo;
import java.util.ArrayList;
import java.util.List;
import entidades.Solicitudrecurso;

/**
 *
 * @author Andres
 */
public class SolicitudJpaController {

    public SolicitudJpaController() {
        emf = Persistence.createEntityManagerFactory("proyectoCongresoPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Solicitud solicitud) throws PreexistingEntityException, Exception {
        if (solicitud.getSolicitudinsumoList() == null) {
            solicitud.setSolicitudinsumoList(new ArrayList<Solicitudinsumo>());
        }
        if (solicitud.getSolicitudrecursoList() == null) {
            solicitud.setSolicitudrecursoList(new ArrayList<Solicitudrecurso>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Carta carta = solicitud.getCarta();
            if (carta != null) {
                carta = em.getReference(carta.getClass(), carta.getCodradicacion());
                solicitud.setCarta(carta);
            }
            List<Solicitudinsumo> attachedSolicitudinsumoList = new ArrayList<Solicitudinsumo>();
            for (Solicitudinsumo solicitudinsumoListSolicitudinsumoToAttach : solicitud.getSolicitudinsumoList()) {
                solicitudinsumoListSolicitudinsumoToAttach = em.getReference(solicitudinsumoListSolicitudinsumoToAttach.getClass(), solicitudinsumoListSolicitudinsumoToAttach.getSolicitudinsumoPK());
                attachedSolicitudinsumoList.add(solicitudinsumoListSolicitudinsumoToAttach);
            }
            solicitud.setSolicitudinsumoList(attachedSolicitudinsumoList);
            List<Solicitudrecurso> attachedSolicitudrecursoList = new ArrayList<Solicitudrecurso>();
            for (Solicitudrecurso solicitudrecursoListSolicitudrecursoToAttach : solicitud.getSolicitudrecursoList()) {
                solicitudrecursoListSolicitudrecursoToAttach = em.getReference(solicitudrecursoListSolicitudrecursoToAttach.getClass(), solicitudrecursoListSolicitudrecursoToAttach.getSolicitudrecursoPK());
                attachedSolicitudrecursoList.add(solicitudrecursoListSolicitudrecursoToAttach);
            }
            solicitud.setSolicitudrecursoList(attachedSolicitudrecursoList);
            em.persist(solicitud);
            if (carta != null) {
                carta.getSolicitudList().add(solicitud);
                carta = em.merge(carta);
            }
            for (Solicitudinsumo solicitudinsumoListSolicitudinsumo : solicitud.getSolicitudinsumoList()) {
                Solicitud oldSolicitudOfSolicitudinsumoListSolicitudinsumo = solicitudinsumoListSolicitudinsumo.getSolicitud();
                solicitudinsumoListSolicitudinsumo.setSolicitud(solicitud);
                solicitudinsumoListSolicitudinsumo = em.merge(solicitudinsumoListSolicitudinsumo);
                if (oldSolicitudOfSolicitudinsumoListSolicitudinsumo != null) {
                    oldSolicitudOfSolicitudinsumoListSolicitudinsumo.getSolicitudinsumoList().remove(solicitudinsumoListSolicitudinsumo);
                    oldSolicitudOfSolicitudinsumoListSolicitudinsumo = em.merge(oldSolicitudOfSolicitudinsumoListSolicitudinsumo);
                }
            }
            for (Solicitudrecurso solicitudrecursoListSolicitudrecurso : solicitud.getSolicitudrecursoList()) {
                Solicitud oldSolicitudOfSolicitudrecursoListSolicitudrecurso = solicitudrecursoListSolicitudrecurso.getSolicitud();
                solicitudrecursoListSolicitudrecurso.setSolicitud(solicitud);
                solicitudrecursoListSolicitudrecurso = em.merge(solicitudrecursoListSolicitudrecurso);
                if (oldSolicitudOfSolicitudrecursoListSolicitudrecurso != null) {
                    oldSolicitudOfSolicitudrecursoListSolicitudrecurso.getSolicitudrecursoList().remove(solicitudrecursoListSolicitudrecurso);
                    oldSolicitudOfSolicitudrecursoListSolicitudrecurso = em.merge(oldSolicitudOfSolicitudrecursoListSolicitudrecurso);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findSolicitud(solicitud.getIdsolicitud()) != null) {
                throw new PreexistingEntityException("Solicitud " + solicitud + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Solicitud solicitud) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Solicitud persistentSolicitud = em.find(Solicitud.class, solicitud.getIdsolicitud());
            Carta cartaOld = persistentSolicitud.getCarta();
            Carta cartaNew = solicitud.getCarta();
            List<Solicitudinsumo> solicitudinsumoListOld = persistentSolicitud.getSolicitudinsumoList();
            List<Solicitudinsumo> solicitudinsumoListNew = solicitud.getSolicitudinsumoList();
            List<Solicitudrecurso> solicitudrecursoListOld = persistentSolicitud.getSolicitudrecursoList();
            List<Solicitudrecurso> solicitudrecursoListNew = solicitud.getSolicitudrecursoList();
            List<String> illegalOrphanMessages = null;
            for (Solicitudinsumo solicitudinsumoListOldSolicitudinsumo : solicitudinsumoListOld) {
                if (!solicitudinsumoListNew.contains(solicitudinsumoListOldSolicitudinsumo)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Solicitudinsumo " + solicitudinsumoListOldSolicitudinsumo + " since its solicitud field is not nullable.");
                }
            }
            for (Solicitudrecurso solicitudrecursoListOldSolicitudrecurso : solicitudrecursoListOld) {
                if (!solicitudrecursoListNew.contains(solicitudrecursoListOldSolicitudrecurso)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Solicitudrecurso " + solicitudrecursoListOldSolicitudrecurso + " since its solicitud field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (cartaNew != null) {
                cartaNew = em.getReference(cartaNew.getClass(), cartaNew.getCodradicacion());
                solicitud.setCarta(cartaNew);
            }
            List<Solicitudinsumo> attachedSolicitudinsumoListNew = new ArrayList<Solicitudinsumo>();
            for (Solicitudinsumo solicitudinsumoListNewSolicitudinsumoToAttach : solicitudinsumoListNew) {
                solicitudinsumoListNewSolicitudinsumoToAttach = em.getReference(solicitudinsumoListNewSolicitudinsumoToAttach.getClass(), solicitudinsumoListNewSolicitudinsumoToAttach.getSolicitudinsumoPK());
                attachedSolicitudinsumoListNew.add(solicitudinsumoListNewSolicitudinsumoToAttach);
            }
            solicitudinsumoListNew = attachedSolicitudinsumoListNew;
            solicitud.setSolicitudinsumoList(solicitudinsumoListNew);
            List<Solicitudrecurso> attachedSolicitudrecursoListNew = new ArrayList<Solicitudrecurso>();
            for (Solicitudrecurso solicitudrecursoListNewSolicitudrecursoToAttach : solicitudrecursoListNew) {
                solicitudrecursoListNewSolicitudrecursoToAttach = em.getReference(solicitudrecursoListNewSolicitudrecursoToAttach.getClass(), solicitudrecursoListNewSolicitudrecursoToAttach.getSolicitudrecursoPK());
                attachedSolicitudrecursoListNew.add(solicitudrecursoListNewSolicitudrecursoToAttach);
            }
            solicitudrecursoListNew = attachedSolicitudrecursoListNew;
            solicitud.setSolicitudrecursoList(solicitudrecursoListNew);
            solicitud = em.merge(solicitud);
            if (cartaOld != null && !cartaOld.equals(cartaNew)) {
                cartaOld.getSolicitudList().remove(solicitud);
                cartaOld = em.merge(cartaOld);
            }
            if (cartaNew != null && !cartaNew.equals(cartaOld)) {
                cartaNew.getSolicitudList().add(solicitud);
                cartaNew = em.merge(cartaNew);
            }
            for (Solicitudinsumo solicitudinsumoListNewSolicitudinsumo : solicitudinsumoListNew) {
                if (!solicitudinsumoListOld.contains(solicitudinsumoListNewSolicitudinsumo)) {
                    Solicitud oldSolicitudOfSolicitudinsumoListNewSolicitudinsumo = solicitudinsumoListNewSolicitudinsumo.getSolicitud();
                    solicitudinsumoListNewSolicitudinsumo.setSolicitud(solicitud);
                    solicitudinsumoListNewSolicitudinsumo = em.merge(solicitudinsumoListNewSolicitudinsumo);
                    if (oldSolicitudOfSolicitudinsumoListNewSolicitudinsumo != null && !oldSolicitudOfSolicitudinsumoListNewSolicitudinsumo.equals(solicitud)) {
                        oldSolicitudOfSolicitudinsumoListNewSolicitudinsumo.getSolicitudinsumoList().remove(solicitudinsumoListNewSolicitudinsumo);
                        oldSolicitudOfSolicitudinsumoListNewSolicitudinsumo = em.merge(oldSolicitudOfSolicitudinsumoListNewSolicitudinsumo);
                    }
                }
            }
            for (Solicitudrecurso solicitudrecursoListNewSolicitudrecurso : solicitudrecursoListNew) {
                if (!solicitudrecursoListOld.contains(solicitudrecursoListNewSolicitudrecurso)) {
                    Solicitud oldSolicitudOfSolicitudrecursoListNewSolicitudrecurso = solicitudrecursoListNewSolicitudrecurso.getSolicitud();
                    solicitudrecursoListNewSolicitudrecurso.setSolicitud(solicitud);
                    solicitudrecursoListNewSolicitudrecurso = em.merge(solicitudrecursoListNewSolicitudrecurso);
                    if (oldSolicitudOfSolicitudrecursoListNewSolicitudrecurso != null && !oldSolicitudOfSolicitudrecursoListNewSolicitudrecurso.equals(solicitud)) {
                        oldSolicitudOfSolicitudrecursoListNewSolicitudrecurso.getSolicitudrecursoList().remove(solicitudrecursoListNewSolicitudrecurso);
                        oldSolicitudOfSolicitudrecursoListNewSolicitudrecurso = em.merge(oldSolicitudOfSolicitudrecursoListNewSolicitudrecurso);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = solicitud.getIdsolicitud();
                if (findSolicitud(id) == null) {
                    throw new NonexistentEntityException("The solicitud with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Solicitud solicitud;
            try {
                solicitud = em.getReference(Solicitud.class, id);
                solicitud.getIdsolicitud();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The solicitud with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Solicitudinsumo> solicitudinsumoListOrphanCheck = solicitud.getSolicitudinsumoList();
            for (Solicitudinsumo solicitudinsumoListOrphanCheckSolicitudinsumo : solicitudinsumoListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Solicitud (" + solicitud + ") cannot be destroyed since the Solicitudinsumo " + solicitudinsumoListOrphanCheckSolicitudinsumo + " in its solicitudinsumoList field has a non-nullable solicitud field.");
            }
            List<Solicitudrecurso> solicitudrecursoListOrphanCheck = solicitud.getSolicitudrecursoList();
            for (Solicitudrecurso solicitudrecursoListOrphanCheckSolicitudrecurso : solicitudrecursoListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Solicitud (" + solicitud + ") cannot be destroyed since the Solicitudrecurso " + solicitudrecursoListOrphanCheckSolicitudrecurso + " in its solicitudrecursoList field has a non-nullable solicitud field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Carta carta = solicitud.getCarta();
            if (carta != null) {
                carta.getSolicitudList().remove(solicitud);
                carta = em.merge(carta);
            }
            em.remove(solicitud);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Solicitud> findSolicitudEntities() {
        return findSolicitudEntities(true, -1, -1);
    }

    public List<Solicitud> findSolicitudEntities(int maxResults, int firstResult) {
        return findSolicitudEntities(false, maxResults, firstResult);
    }

    private List<Solicitud> findSolicitudEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Solicitud.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Solicitud findSolicitud(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Solicitud.class, id);
        } finally {
            em.close();
        }
    }

    public int getSolicitudCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Solicitud> rt = cq.from(Solicitud.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
